Skip to content

feat: Add integration tests - #195

Open
hhvrc wants to merge 22 commits into
developfrom
feat/integration-tests
Open

feat: Add integration tests#195
hhvrc wants to merge 22 commits into
developfrom
feat/integration-tests

Conversation

@hhvrc

@hhvrc hhvrc commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@hhvrc hhvrc self-assigned this Apr 28, 2026
Comment thread e2e/e2e/lib/test-fixtures.ts Fixed
Comment thread e2e/e2e/lib/test-fixtures.ts Fixed
Comment thread e2e/integration/lib/api-client.ts Fixed
Comment thread e2e/integration/lib/test-fixtures.ts Fixed
Comment thread e2e/integration/lib/test-fixtures.ts Fixed
Comment thread playwright.integration.config.ts Fixed
Comment thread src/lib/state/color-scheme-state.test.svelte.ts Fixed
Comment thread src/lib/state/color-scheme-state.test.svelte.ts Fixed
Comment thread src/lib/state/color-scheme-state.test.svelte.ts Fixed
Comment thread e2e/e2e/login-logout.spec.ts Fixed
Comment thread e2e/e2e/login-logout.spec.ts Fixed
Comment thread e2e/e2e/login-logout.spec.ts Fixed
Comment thread e2e/integration/auth.spec.ts Fixed
Comment thread e2e/integration/auth.spec.ts Fixed
Comment thread playwright.config.ts Fixed
Comment thread scripts/dev-integration.mjs Dismissed
@hhvrc
hhvrc marked this pull request as ready for review May 6, 2026 21:37
Copilot AI lite review requested due to automatic review settings May 6, 2026 21:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a full integration-testing scaffold (Playwright + Docker-backed backend) and expands the unit/component test setup (Vitest projects + Testing Library) to improve confidence in both frontend state modules and end-to-end user journeys.

Changes:

  • Added Playwright “integration” test suite that boots a local docker-compose backend and runs against a Vite integration mode.
  • Split Vitest into unit vs jsdom/component projects and added a large set of new unit/component tests across state, API helpers, and SignalR handlers.
  • Introduced small runtime fixes (auth state reset when unauthenticated, safer navigation state tracking, empty-state UI) plus basic security headers via hooks.server.ts.

Reviewed changes

Copilot reviewed 59 out of 60 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
vitest.setup.ts Adds jest-dom matchers for Vitest (jsdom/component tests).
vite.config.ts Adds integration-mode env loading, Vite proxying for /1 & /2, Vitest multi-project setup, and integration TLS behavior.
src/routes/+error.svelte Makes afterNavigate handling null-safe with optional chaining.
src/routes/(app)/shares/user/outgoing/+page.svelte Adds outgoing-shares empty state UI.
src/routes/(app)/settings/api-tokens/+page.svelte Fixes token creation state update to use reassignment (reactivity-friendly).
src/lib/state/user-state.test.svelte.ts Adds tests for user state behavior and refreshSelf paths.
src/lib/state/user-shares-state.test.svelte.ts Adds tests for shares state refresh functions and error handling.
src/lib/state/shared-hubs-state.test.svelte.ts Adds tests for shared hubs state initialization and refresh.
src/lib/state/live-control-state.test.svelte.ts Adds extensive tests for live-control state, WebSocket handling, and helpers.
src/lib/state/hubs-state.test.svelte.ts Adds tests for hubs state and refreshOwnHubs behavior.
src/lib/state/color-scheme-state.test.svelte.ts Adds jsdom tests for theme handling and DarkReader detection.
src/lib/state/breadcrumbs-state.test.svelte.ts Adds tests for breadcrumb registration lifecycle via fixture component.
src/lib/state/backend-metadata-state.test.svelte.ts Adds tests for backend metadata initialization and error cases.
src/lib/state/fixtures/BreadcrumbRegistrar.svelte Test fixture component for breadcrumb registration.
src/lib/signalr/handlers/OtaRollback.test.ts Adds tests for OTA rollback SignalR handler effects/toasts.
src/lib/signalr/handlers/OtaInstallProgress.test.ts Adds tests for OTA progress handler updates and validation.
src/lib/signalr/handlers/Log.test.ts Adds tests for SignalR log validation and listener dispatch behavior.
src/lib/signalr/handlers/DeviceUpdate.test.ts Adds tests for device update handler routing and validation.
src/lib/signalr/handlers/DeviceStatus.test.ts Adds tests for device status handler behavior and validation.
src/lib/components/ui/data-table/mergeObjects.test.ts Adds tests for mergeObjects proxy/override behavior.
src/lib/components/dialog-manager/dialog-store.test.svelte.ts Adds tests for dialog store creation/removal and confirm/alert flows.
src/lib/api/pwnedPasswords.test.ts Adds tests for HIBP range lookup parsing and error handling.
src/lib/api/firmwareCDN.test.ts Adds tests for firmware CDN fetching/parsing and hash verification.
src/hooks.server.ts Adds security headers (nosniff, SAMEORIGIN) globally.
src/hooks.client.ts Resets userState when backend says the user is unauthenticated.
scripts/dev-integration.mjs Starts docker-compose integration stack, waits for backend, then launches Vite integration mode.
README.md Adds CI badge entries for the new integration workflow.
pnpm-lock.yaml Adds Testing Library + jsdom dependencies and updates Vitest peer graph.
playwright.e2e.config.ts Adds separate “full E2E” Playwright config targeting a remote environment.
playwright.config.ts Replaces default config with integration-focused Playwright setup + docker-backed webServer.
package.json Adds dev:integration, splits test:integration vs test:e2e, updates test script.
eslint.config.js Disables no-explicit-any for test files.
e2e/integration/smoke.spec.ts Adds baseline smoke coverage for integration harness + fixtures.
e2e/integration/signalr.spec.ts Adds SignalR lifecycle checks (no errors) and request observation.
e2e/integration/shockers.spec.ts Adds basic route render/empty-state checks for shockers/hubs pages.
e2e/integration/shares.spec.ts Adds basic route checks for share pages + non-500 on fake share link.
e2e/integration/sessions-connections.spec.ts Adds basic checks for sessions and connections pages.
e2e/integration/public-pages.spec.ts Adds checks for public pages and auth redirects for protected routes.
e2e/integration/oauth-and-password-reset.spec.ts Adds basic UI checks for OAuth buttons and password reset page behavior.
e2e/integration/live-control.spec.ts Adds basic route checks for live-control related pages and fake IDs.
e2e/integration/lib/test-fixtures.ts Adds API-driven user lifecycle + cookie injection fixtures for integration tests.
e2e/integration/lib/global-teardown.ts Adds CI-only docker-compose shutdown for integration runs.
e2e/integration/lib/global-setup.ts Placeholder globalSetup (docker started by webServer script).
e2e/integration/lib/env.ts Centralizes integration test env defaults.
e2e/integration/lib/api-client.ts Adds API client helpers for signup/activate/login/delete/logout via backend + MailPit.
e2e/integration/cross-cutting.spec.ts Adds cross-cutting checks (headers, 404 behavior, navigation, responsiveness).
e2e/integration/auth.spec.ts Adds integration-level tests for login/signup/logout flows.
e2e/integration/api-tokens.spec.ts Adds integration tests for token creation/listing/deletion via UI.
e2e/integration/admin.spec.ts Adds non-admin coverage ensuring admin routes don’t 500 and handle denial.
e2e/integration/account-settings.spec.ts Adds basic settings/profile/session UI checks.
e2e/indexpage.test.ts Removes the old single Playwright test in favor of the new structure.
e2e/e2e/signup-verify.spec.ts Adds full E2E signup/verify/login tests (MailPit-gated).
e2e/e2e/login-logout.spec.ts Adds full E2E UI-level login/logout structure tests.
e2e/e2e/lib/test-fixtures.ts Adds full E2E fixtures including Turnstile bypass and teardown deletion.
e2e/e2e/lib/mailpit.ts Adds MailPit API helpers for polling emails and extracting links.
e2e/e2e/lib/env.ts Adds full E2E env defaults (next.openshock.dev, optional MailPit).
e2e/e2e/lib/api-client.ts Minimal API client for full E2E teardown/logout.
docker-compose.integration.yml Adds integration backend stack (postgres/redis/mailpit/api) for local+CI.
.github/workflows/ci-integration.yml Adds CI job to run integration tests with Playwright + cached browsers.
.env.integration Adds Vite integration-mode env values (proxy target + site URLs).
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread vite.config.ts
Comment thread vite.config.ts Outdated
Comment thread e2e/integration/lib/test-fixtures.ts Outdated
Comment thread e2e/integration/signalr.spec.ts Outdated
Comment thread e2e/integration/sessions-connections.spec.ts Outdated
Comment thread playwright.config.ts Outdated
Comment thread e2e/integration/sessions-connections.spec.ts Outdated
hhvrc and others added 5 commits May 6, 2026 23:56
Replace docker-compose.integration.yml with scripts/integration-stack.mjs;
update dev-integration setup/teardown and session-connection tests accordingly.
Resolve conflicts and migrate OpenAPI client to @hey-api/openapi-ts.
Set cpu-features, protobufjs, and ssh2 build scripts to false in
pnpm-workspace.yaml (dev-only Testcontainers deps with optional builds).
Resolve conflicts and realign integration-test work with develop's
regenerated API:

- vite.config.ts: keep develop's pure resolveServerConfig +
  localDevChecksPlugin refactor; layer the branch's integration features
  on top (API proxy, VITE_ env loading, isVitest guard, NODE_TLS for
  integration mode, unit/components vitest projects).
- package.json: take develop's dependency bumps, keep the added test
  deps (@testing-library/*, jsdom, testcontainers) and integration scripts.
- Drop hooks.server.ts to match develop (temporal polyfill now self-guards
  in hooks.client.ts); the security headers it added are out of scope here.
- shares/outgoing: use develop's EmptyState empty state.
- Update state tests to develop's tree-shaken API surface (usersGetSelf,
  userShares*, backendMetadata.set) and ApiUserSelf.hasPassword.
- Fix Log.test.ts to assert the (sender, log) listener signature.
- Remove cross-cutting security-header tests for the dropped headers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the self-signed/mkcert TLS setup from the integration harness and
talk to the API and Vite dev server over plain HTTP instead. The browser
only ever talks to the Vite origin (same-origin, no CORS), and the API
proxy strips Secure/SameSite=None from set-cookie so the session cookie
survives over HTTP. Removes NODE_TLS_REJECT_UNAUTHORIZED and
ignoreHTTPSErrors workarounds.
@ghost

ghost commented Jun 23, 2026

Copy link
Copy Markdown

Ready to review this PR? Stage has broken it down into 8 individual chapters for you:

Title
1 Configure Vitest for unit and component testing
2 Add unit tests for core state and logic
3 Set up integration test infrastructure
4 Configure Playwright for integration and E2E
5 Implement integration test suite
6 Implement full E2E test suite
7 Finalize CI and documentation
8 Other changes
Open in Stage

Chapters generated by Stage for commit 769107b on Jun 23, 2026 3:18pm UTC.

The rebase onto develop landed these tests on a codebase where the API
client exposes flat per-endpoint functions instead of grouped Api objects,
userState/backendMetadata semantics changed, and several tested modules
(pwnedPasswords, dialog-manager, data-table mergeObjects, color-scheme
state) moved into @openshock/svelte-core.

- Rewrite mocks against the flat $lib/api exports
- Update live-control tests for the v2 LCG endpoint (host/port/pathPrefix)
- Rewrite backend-metadata tests for the set()-only store
- Add hasPassword to ApiUserSelf fixtures
- Drop tests whose subjects now live in svelte-core (port them there)
- Declare allowBuilds for testcontainers' native subdeps
Copilot AI review requested due to automatic review settings August 4, 2026 11:20
- prettier: instrumentation.server.ts (unformatted on develop, fails ci-lint
  there too)
- eslint: justify the deliberate this-alias in AlsContextManager.bind

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Suppressed comments (6)

.github/workflows/ci-integration.yml:33

  • Other workflows pin GitHub Actions to commit SHAs (e.g. .github/workflows/ci-build.yml:37). Pin pnpm/action-setup here as well to avoid depending on a mutable @v6 tag.
      - uses: pnpm/action-setup@v6

.github/workflows/ci-integration.yml:42

  • Other workflows pin GitHub Actions to commit SHAs (e.g. .github/workflows/ci-build.yml:32). Pin actions/setup-node here as well to keep supply-chain protections consistent.
      - name: Install Node.js
        uses: actions/setup-node@v6
        with:
          node-version-file: .nvmrc
          cache: 'pnpm'

scripts/dev-integration.mjs:81

  • shutdown() re-sends SIGINT/SIGTERM to the current process while those signals still have handlers installed (the loop below). That prevents the default termination behaviour and can leave dev:integration hanging after Ctrl+C / SIGTERM (stack stops, but process never exits). Remove the signal handlers before re-killing, or just process.exit() after cleanup.
    e2e/integration/signalr.spec.ts:23
  • Typo in variable name: signarErrors looks like it should be signalrErrors (matches the test intent and regex).
    // Filter out noise unrelated to SignalR
    const signarErrors = errors.filter((e) => /signalr|websocket|hub|negotiate/i.test(e));
    expect(signarErrors).toHaveLength(0);

.github/workflows/ci-integration.yml:32

  • Other workflows pin GitHub Actions to full commit SHAs (e.g. .github/workflows/ci-build.yml:27), but this workflow uses floating version tags. Pinning here too improves supply-chain safety and keeps conventions consistent.

This issue also appears in the following locations of the same file:

  • line 33
  • line 38
      - name: Checkout
        uses: actions/checkout@v6

e2e/integration/lib/test-fixtures.ts:47

  • Defaulting cookie domain to the backend host (apiHost) means auth cookies won’t be sent when TEST_FRONTEND_URL and TEST_BACKEND_URL have different hostnames (e.g. 127.0.0.1 vs localhost). Default to the frontend hostname for Playwright context cookies in this harness (and keep apiHost only as a fallback/consistency check).
        domain: attrMap['domain'] ?? apiHost,

Copilot AI review requested due to automatic review settings August 4, 2026 11:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Suppressed comments (4)

vite.config.ts:273

  • Integration mode relies on a fixed baseURL (default http://localhost:5173) in Playwright. Consider enabling strictPort: true so Vite fails fast instead of silently switching to another port when 5173 is already in use (which would make the integration runner probe the wrong origin).
    vite.config.ts:202
  • LocalServer.config is used as the Vite server config shape, but it currently omits strictPort. In integration mode the Playwright baseURL is fixed to http://localhost:5173; without strictPort, Vite will auto-increment the port if 5173 is taken, causing the integration runner to probe the wrong URL.

This issue also appears on line 269 of the same file.
vite.config.ts:261

  • proxyRes.headers['set-cookie'] can be either a string or an array of strings. Calling .map unconditionally will throw when only a single cookie is set (string case). Normalize to an array before mapping.
    e2e/integration/signalr.spec.ts:23
  • Typo in variable name: signarErrorssignalErrors. Keeping the correct spelling makes the intent clearer and avoids copy/paste typos elsewhere.
    const signarErrors = errors.filter((e) => /signalr|websocket|hub|negotiate/i.test(e));
    expect(signarErrors).toHaveLength(0);

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
openshock-app be25347 Aug 04 2026, 11:25 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants